package protocol

//网络协议的数字均是以大端方式处理

import (
	"bytes"
	"encoding/binary"
	"errors"
	"fmt"
	"reflect"
	"runtime"
	"unsafe"
)

const t_max_package_size = 0xFFFF - 2 //减2是因为组成网络包时，前面还需要加2个byte,表示包长度。
const (
	t_one = 200 + iota
	t_keyvalue
	t_struct
)

// 字节数据转单个基本类型值
func GetValueFromBytes(data []byte) (any, error) {
	if data[0] != t_one {
		return nil, errors.New(Err_DataFormtError)
	}
	value, _, _, err := getValueFromByte(data[1:])
	if err != nil {
		return nil, err
	}
	return value, nil
}

// 单个基本类型值转字节数组
func GetBytesFromValue(data any) ([]byte, error) {
	buffer := bytes.NewBuffer(nil)
	buffer.WriteByte(t_one)
	err := getByteFromData(buffer, data)
	if err != nil {
		return nil, err
	}
	if uint16(buffer.Len()) >= t_max_package_size {
		return nil, fmt.Errorf("package length >= 2byte-2")
	}
	return buffer.Bytes(), nil
}

// Key-Value模型两个基本数据类型值转换字节数组
func GetBytesFromKeyValue(key any, value any) ([]byte, error) {
	buffer := bytes.NewBuffer(nil)
	buffer.WriteByte(t_keyvalue)

	err := getByteFromData(buffer, key)
	if err != nil {
		return nil, err
	}
	err = getByteFromData(buffer, value)
	if err != nil {
		return nil, err
	}
	if uint16(buffer.Len()) >= t_max_package_size {
		return nil, fmt.Errorf("package length >= 2byte-2")
	}
	return buffer.Bytes(), nil
}

// 字节数组转换两个基本类型值，Key-Value模型
func GetKeyValueFromBytes(data []byte) (any, any, error) {
	if data[0] != t_keyvalue {
		return nil, nil, errors.New(Err_DataFormtError)
	}
	a, _, index, err1 := getValueFromByte(data[1:])
	if err1 != nil {
		return nil, nil, err1
	}
	aa, _, _, err2 := getValueFromByte(data[1+index:])
	if err2 != nil {
		return nil, nil, err2
	}
	return a, aa, nil
}

/*
结构体需满足以下条件才可以转流：
1、字段类型只能是基本类型及基本类型数组，不能是切片，不能自定义类型,即结构体内部包含自定义结构体值
2、字段名称必须是大写字母，即需要外部能该问
3、结构体转字节流只能是实体对象，不能是指针
4、字节流转结构体，结构体必须要先初始化，且带入的只能是指针
5、结构体内部最多只能是255个字段，且每个字段的名称长度也只能是255,因为只是用了一个字节来存储长度
6、字节流按结构体字段顺序存储，相互转换，结构体的字段顺序要保持一致
*/
//字节流内部存储方式
// 1byte(t_struct)+1byte(字段数量)+循环取[1byte(字段名称长度)+nbyte(字段名称)+字段值]

func GetBytesFromStruct(obj any) ([]byte, error) {
	pVal := reflect.ValueOf(obj)
	if pVal.Kind() == reflect.Ptr {
		return nil, fmt.Errorf("obj is point ptr,it's must struct")
	}

	// 检查是否为结构体
	if pVal.Kind() != reflect.Struct {
		return nil, fmt.Errorf("obj is not struct")
	}

	bufs := bytes.NewBuffer(nil)
	bufs.WriteByte(t_struct)

	pType := reflect.TypeOf(obj)
	if pType.NumField() > 0xFF {
		return nil, fmt.Errorf("struct fieldnum > 255")
	}
	bufs.WriteByte(byte(pType.NumField()))

	for i := 0; i < pType.NumField(); i++ {
		fieldInfo := pType.Field(i) // 字段类型信息
		fieldVal := pVal.Field(i)   // 字段值信息
		name := fieldInfo.Name

		bufs.WriteByte(byte(len(name)))
		if len(name) > 0xFF {
			return nil, fmt.Errorf("fieldname length > 255")
		}
		bufs.WriteString(name)

		vv := fieldVal.Interface()

		getByteFromData(bufs, vv)
	}
	if uint16(bufs.Len()) >= t_max_package_size {
		return nil, fmt.Errorf("package length >= 2byte-2")
	}
	return bufs.Bytes(), nil
}

func GetStructFromBytes(data []byte, target any) error {
	if data[0] != t_struct {
		return errors.New(Err_DataFormtError)
	}

	//取字段数量
	l := data[1]
	index := 2

	for i := 0; i < int(l); i++ {
		fl := data[index] //取字段名称长度
		index++

		name := data[index : index+int(fl)]
		index += int(fl)

		if fv, _, b, err := getValueFromByte(data[index:]); err != nil {
			return err
		} else {
			index += int(b)
			if err1 := setFieldValue(target, string(name), fv); err1 != nil {
				return err1
			}
		}
	}
	return nil
}

// /////////////////////////////////////////////////////////////////////
//以下是未对外公布函数模块区域

func setFieldValue(v any, fieldName string, value any) error {
	// 获取反射值，必须是指针类型才能设置值
	val := reflect.ValueOf(v)
	if val.Kind() != reflect.Ptr {
		return fmt.Errorf("v is must point ptr")
	}
	val = val.Elem() // 解引用指针

	// 检查是否为结构体
	if val.Kind() != reflect.Struct {
		return fmt.Errorf("point ptr=%s is't struct,", val.Kind().String())
	}

	// 根据字段名获取字段
	field := val.FieldByName(fieldName)
	if !field.IsValid() {
		return fmt.Errorf("struct not found fieldname:%s", fieldName)
	}

	// 检查字段是否可设置（必须是导出字段，首字母大写）
	if !field.CanSet() {
		return fmt.Errorf("field %s not public set", fieldName)
	}

	// 将输入值转换为字段对应的类型
	valueVal := reflect.ValueOf(value)
	if valueVal.Type() != field.Type() {
		return fmt.Errorf("value is error,fieldtype: %s, input fieldtype: %s",
			field.Type(), valueVal.Type())
	}

	// 设置字段值
	field.Set(valueVal)
	return nil
}

// 与上面是一对,只是未使用，保留代码
func getFieldValue(v any, fieldName string) (any, error) {
	// 获取反射值，处理指针类型
	val := reflect.ValueOf(v)
	if val.Kind() == reflect.Ptr {
		val = val.Elem() // 解引用指针
	}

	// 检查是否为结构体
	if val.Kind() != reflect.Struct {
		return nil, fmt.Errorf("输入不是结构体或结构体指针")
	}

	// 根据字段名获取字段
	field := val.FieldByName(fieldName)
	if !field.IsValid() {
		return nil, fmt.Errorf("结构体中不存在字段: %s", fieldName)
	}

	// 返回字段值（转为interface{}）
	return field.Interface(), nil
}

// 能处理的数据类型,从字面意思应该能理解
const (
	t_byte = 0 + iota
	t_bool
	t_int8
	t_int16
	t_uint16
	t_int
	t_uint
	t_int32
	t_uint32
	t_int64
	t_uint64
	t_float32
	t_float64
	t_complex64
	t_complex128
	t_string = 128 + iota
	t_byte_array
	t_bool_array
	t_int8_array
	t_int16_array
	t_uint16_array
	t_int_array
	t_uint_array
	t_int32_array
	t_uint32_array
	t_int64_array
	t_uint64_array
	t_float32_array
	t_float64_array
	t_complex64_array
	t_complex128_array
	t_string_array
)

// 判断操作系统是32位还是64位，从而确定int及uint的大小
func getOSArch() int {
	arch := runtime.GOARCH
	cc := 32
	// 判断位数
	switch arch {
	case "386", "arm":
		{
			cc = 32
		}
	case "amd64", "arm64", "ppc64", "ppc64le", "s390x":
		{
			cc = 64
		}
	default:
		{
			cc = 32
		}
	}
	return cc
}

// 定义自定义错误常量
const (
	Err_DataTooShort   = "data too short"
	Err_DataFormtError = "data format error"
)

// 数据设计：byte(类型,最高位是1，表示有长度值)+长度（2byte,可选）+数据
// 返回值：第一个any=数据本体，第二个uint16=数据本体个数,第三个是在检索数据包的字节序号，error=出错信息
func getValueFromByte(data []byte) (any, uint16, uint16, error) {
	//取OS的多少位，结果是32或64。
	cc := getOSArch()
	length := len(data)

	//第一个值代表数据类型
	flag := data[0]
	switch flag {
	case t_byte, t_bool, t_int8:
		{
			if length >= 2 {
				var res byte = data[1]
				switch flag {
				case t_byte:
					{
						return byte(res), 1, 2, nil
					}
				case t_bool:
					{
						if res >= 1 {
							return true, 1, 2, nil
						} else {
							return false, 1, 2, nil
						}
					}
				case t_int8:
					{
						return int8(res), 1, 2, nil
					}
				}

			} else {
				return byte(0), 0, 0, errors.New(Err_DataTooShort)
			}
		}
	case t_int16, t_uint16:
		{
			if length >= 3 {
				var res = binary.BigEndian.Uint16(data[1:])
				if flag == t_int16 {
					return int16(res), 1, 3, nil
				}
				return res, 1, 3, nil
			} else {
				return 0, 0, 0, errors.New(Err_DataTooShort)
			}
		}
	case t_int, t_uint:
		{
			if cc == 32 {
				if length >= 5 {
					var res = binary.BigEndian.Uint32(data[1:])
					if flag == t_int {
						return int(res), 1, 5, nil
					}
					return uint(res), 1, 5, nil
				} else {
					return 0, 0, 0, errors.New(Err_DataTooShort)
				}
			}
			if cc == 64 {
				if length >= 9 {
					var res = binary.BigEndian.Uint64(data[1:])
					if flag == t_int {
						return int(res), 1, 9, nil
					}
					return uint(res), 1, 9, nil
				} else {
					return 0, 0, 0, errors.New(Err_DataTooShort)
				}
			}
		}
	case t_int32, t_uint32:
		{
			if length >= 5 {
				var res = binary.BigEndian.Uint32(data[1:])
				if flag == t_int32 {
					return int32(res), 1, 5, nil
				}
				return res, 1, 5, nil
			} else {
				return 0, 0, 0, errors.New(Err_DataTooShort)
			}
		}
	case t_int64, t_uint64:
		{
			if length >= 9 {
				var res = binary.BigEndian.Uint64(data[1:])
				if flag == t_int64 {
					return int64(res), 1, 9, nil
				}
				return res, 1, 9, nil
			} else {
				return 0, 0, 0, errors.New(Err_DataTooShort)
			}
		}
	case t_float32: //4字节
		{
			if length >= 5 {
				var res = binary.BigEndian.Uint32(data[1:])
				var res1 float32 = *(*float32)(unsafe.Pointer(&res))
				return res1, 1, 5, nil
			} else {
				return 0.0, 0, 0, errors.New(Err_DataTooShort)
			}
		}
	case t_float64: //8字节
		{
			if length >= 9 {
				var res = binary.BigEndian.Uint64(data[1:])
				var res1 float64 = *(*float64)(unsafe.Pointer(&res))
				return res1, 1, 9, nil
			} else {
				return 0.0, 0, 0, errors.New(Err_DataTooShort)
			}
		}
	case t_complex64: //8字节
		{
			if length >= 9 {
				var res = binary.BigEndian.Uint32(data[1:])
				var a float32 = *(*float32)(unsafe.Pointer(&res))

				var res1 = binary.BigEndian.Uint32(data[5:])
				var bi float32 = *(*float32)(unsafe.Pointer(&res1))
				var c complex64 = complex(a, bi)
				return c, 1, 9, nil
			} else {
				return 0.0, 0, 0, errors.New(Err_DataTooShort)
			}
		}
	case t_complex128:
		{
			if length >= 17 {
				var res = binary.BigEndian.Uint64(data[1:])
				var a float64 = *(*float64)(unsafe.Pointer(&res))

				var res1 = binary.BigEndian.Uint64(data[9:])
				var bi float64 = *(*float64)(unsafe.Pointer(&res1))
				var c complex128 = complex(a, bi)
				return c, 1, 17, nil
			} else {
				return 0.0, 0, 0, errors.New(Err_DataTooShort)
			}
		}
	case t_string:
		{
			//数据长度
			if length >= 3 {
				var length1 = binary.BigEndian.Uint16(data[1:])
				if length >= 3+int(length1) {
					return string(data[3 : 3+length1]), 1, 3 + length1, nil
				} else {
					return "", 0, 0, errors.New(Err_DataTooShort)
				}
			} else {
				return "", 0, 0, errors.New(Err_DataTooShort)
			}
		}
	case t_byte_array:
		{
			//数据长度
			if length >= 3 {
				var length1 = binary.BigEndian.Uint16(data[1:])
				if length >= 3+int(length1) {
					return data[3 : 3+length1], length1, 3 + length1, nil
				} else {
					return nil, 0, 0, errors.New(Err_DataTooShort)
				}
			} else {
				return nil, 0, 0, errors.New(Err_DataTooShort)
			}
		}
	case t_int8_array:
		{
			if length >= 3 {
				//数据长度
				var leng = binary.BigEndian.Uint16(data[1:])
				if length >= int(leng)+3 {
					result := make([]int8, leng)
					index := 3
					for i := 0; i < int(leng); i++ {
						result[i] = int8(data[index])
						index++
					}
					return result, leng, uint16(index), nil
				} else {
					return nil, 0, 0, errors.New(Err_DataTooShort)
				}
			} else {
				return nil, 0, 0, errors.New(Err_DataTooShort)
			}
		}
	case t_bool_array:
		{
			//数据长度
			if length >= 3 {
				var leng = binary.BigEndian.Uint16(data[1:])
				if length >= 3+int(leng) {
					result := make([]bool, leng)
					index := 3
					for i := 0; i < int(leng); i++ {
						if data[index] >= 1 {
							result[i] = true
						} else {
							result[i] = false
						}
						index++
					}
					return result, leng, uint16(index), nil
				} else {
					return nil, 0, 0, errors.New(Err_DataTooShort)
				}
			} else {
				return nil, 0, 0, errors.New(Err_DataTooShort)
			}
		}
	case t_int16_array, t_uint16_array:
		{
			if length >= 3 {
				var leng = binary.BigEndian.Uint16(data[1:])
				index := 3
				if length >= int(leng)+3 {
					if flag == t_int16_array {
						result := make([]int16, leng)
						for i := 0; i < int(leng); i++ {
							var res uint16 = binary.BigEndian.Uint16(data[index:])
							index += 2
							result[i] = int16(res)
						}
						return result, leng, uint16(index), nil
					}
					result := make([]uint16, leng)
					for i := 0; i < int(leng); i++ {
						var res uint16 = binary.BigEndian.Uint16(data[index:])
						index += 2
						result[i] = res
					}
					return result, leng, uint16(index), nil
				} else {
					return nil, 0, 0, errors.New(Err_DataTooShort)
				}
			} else {
				return nil, 0, 0, errors.New(Err_DataTooShort)
			}
		}
	case t_int32_array, t_uint32_array:
		{
			if length >= 3 {
				var leng = binary.BigEndian.Uint16(data[1:])
				index := 3
				if length >= int(leng)+3 {
					if flag == t_int32_array {
						result := make([]int32, leng)
						for i := 0; i < int(leng); i++ {
							var res uint32 = binary.BigEndian.Uint32(data[index:])
							index += 4
							result[i] = int32(res)
						}
						return result, leng, uint16(index), nil
					}
					result := make([]uint32, leng)
					for i := 0; i < int(leng); i++ {
						var res uint32 = binary.BigEndian.Uint32(data[index:])
						index += 4
						result[i] = res
					}
					return result, leng, uint16(index), nil
				} else {
					return nil, 0, 0, errors.New(Err_DataTooShort)
				}
			} else {
				return nil, 0, 0, errors.New(Err_DataTooShort)
			}
		}
	case t_int_array, t_uint_array:
		{
			if length >= 3 {
				var leng = binary.BigEndian.Uint16(data[1:])
				index := 3
				if length >= int(leng)+3 {
					if cc == 32 {
						if flag == t_int_array {
							result := make([]int, leng)
							for i := 0; i < int(leng); i++ {
								var res uint32 = binary.BigEndian.Uint32(data[index:])
								index += 4
								result[i] = int(res)
							}
							return result, leng, uint16(index), nil
						}
						result := make([]uint, leng)
						for i := 0; i < int(leng); i++ {
							var res uint32 = binary.BigEndian.Uint32(data[index:])
							index += 4
							result[i] = uint(res)
						}
						return result, leng, uint16(index), nil
					} else {
						if flag == t_int_array {
							result := make([]int, leng)
							for i := 0; i < int(leng); i++ {
								var res uint64 = binary.BigEndian.Uint64(data[index:])
								index += 8
								result[i] = int(res)
							}
							return result, leng, uint16(index), nil
						}
						result := make([]uint, leng)
						for i := 0; i < int(leng); i++ {
							var res uint64 = binary.BigEndian.Uint64(data[index:])
							index += 8
							result[i] = uint(res)
						}
						return result, leng, uint16(index), nil
					}
				} else {
					return nil, 0, 0, errors.New(Err_DataTooShort)
				}
			} else {
				return nil, 0, 0, errors.New(Err_DataTooShort)
			}
		}
	case t_int64_array, t_uint64_array:
		{
			if length >= 3 {
				var leng = binary.BigEndian.Uint16(data[1:])
				index := 3
				if length >= int(leng)+3 {
					if flag == t_int64_array {
						result := make([]int64, leng)
						for i := 0; i < int(leng); i++ {
							var res uint64 = binary.BigEndian.Uint64(data[index:])
							index += 8
							result[i] = int64(res)
						}
						return result, leng, uint16(index), nil
					}
					result := make([]uint64, leng)
					for i := 0; i < int(leng); i++ {
						var res uint64 = binary.BigEndian.Uint64(data[index:])
						index += 8
						result[i] = res
					}
					return result, leng, uint16(index), nil
				} else {
					return nil, 0, 0, errors.New(Err_DataTooShort)
				}
			} else {
				return nil, 0, 0, errors.New(Err_DataTooShort)
			}
		}
	case t_float32_array:
		{
			if length >= 3 {
				var leng = binary.BigEndian.Uint16(data[1:])
				index := 3
				if length >= int(leng)+3 {
					result := make([]float32, leng)
					for i := 0; i < int(leng); i++ {
						var res uint32 = binary.BigEndian.Uint32(data[index:])
						index += 4
						var res1 float32 = *(*float32)(unsafe.Pointer(&res))
						result[i] = res1
					}
					return result, leng, uint16(index), nil
				} else {
					return nil, 0, 0, errors.New(Err_DataTooShort)
				}
			} else {
				return nil, 0, 0, errors.New(Err_DataTooShort)
			}
		}
	case t_float64_array:
		{
			if length >= 3 {
				var leng = binary.BigEndian.Uint16(data[1:])
				index := 3
				if length >= int(leng)+3 {
					result := make([]float64, leng)
					for i := 0; i < int(leng); i++ {
						var res uint64 = binary.BigEndian.Uint64(data[index:])
						index += 8
						var res1 float64 = *(*float64)(unsafe.Pointer(&res))
						result[i] = res1
					}
					return result, leng, uint16(index), nil
				} else {
					return nil, 0, 0, errors.New(Err_DataTooShort)
				}
			} else {
				return nil, 0, 0, errors.New(Err_DataTooShort)
			}
		}
	case t_complex64_array:
		{
			if length >= 3 {
				var leng = binary.BigEndian.Uint16(data[1:])
				index := 3
				if length >= int(leng)+3 {
					result := make([]complex64, leng)
					for i := 0; i < int(leng); i++ {
						var res = binary.BigEndian.Uint32(data[index:])
						var a float32 = *(*float32)(unsafe.Pointer(&res))
						index += 4

						var res1 = binary.BigEndian.Uint32(data[index:])
						var bi float32 = *(*float32)(unsafe.Pointer(&res1))
						index += 4

						var c complex64 = complex(a, bi)
						result[i] = c
					}
					return result, leng, uint16(index), nil
				} else {
					return nil, 0, 0, errors.New(Err_DataTooShort)
				}
			} else {
				return nil, 0, 0, errors.New(Err_DataTooShort)
			}
		}
	case t_complex128_array:
		{
			if length >= 3 {
				var leng = binary.BigEndian.Uint16(data[1:])
				index := 3
				if length >= int(leng)+3 {
					result := make([]complex128, leng)
					for i := 0; i < int(leng); i++ {
						var res = binary.BigEndian.Uint64(data[index:])
						var a float64 = *(*float64)(unsafe.Pointer(&res))
						index += 8

						var res1 = binary.BigEndian.Uint64(data[index:])
						var bi float64 = *(*float64)(unsafe.Pointer(&res1))
						index += 8

						var c complex128 = complex(a, bi)
						result[i] = c
					}
					return result, leng, uint16(index), nil
				} else {
					return nil, 0, 0, errors.New(Err_DataTooShort)
				}
			} else {
				return nil, 0, 0, errors.New(Err_DataTooShort)
			}
		}
	case t_string_array:
		{
			if length >= 3 {
				//数据长度
				var leng = binary.BigEndian.Uint16(data[1:])
				index := 3
				if length >= int(leng)+3 {
					result := make([]string, leng)
					for i := 0; i < int(leng); i++ {
						var cc uint16 = binary.BigEndian.Uint16(data[index:])
						index += 2
						result[i] = string(data[index : index+int(cc)])
						index += int(cc)
					}
					return result, leng, uint16(index), nil
				} else {
					return nil, 0, 0, errors.New(Err_DataTooShort)
				}
			} else {
				return nil, 0, 0, errors.New(Err_DataTooShort)
			}
		}
	default:
		{
			return 0, 0, 0, errors.New(Err_DataFormtError)
		}
	}
	return 0, 0, 0, errors.New(Err_DataFormtError)
}

func getByteFromData(buffer *bytes.Buffer, x any) error {
	cc := getOSArch()

	switch v := x.(type) {
	case byte:
		buffer.WriteByte(t_byte)
		binary.Write(buffer, binary.BigEndian, byte(v))
	case []byte:
		{
			buffer.WriteByte(t_byte_array)
			binary.Write(buffer, binary.BigEndian, uint16(len(v)))
			buffer.Write(v)
		}
	case int8:
		buffer.WriteByte(t_int8)
		binary.Write(buffer, binary.BigEndian, int8(v))
	case []int8:
		{
			buffer.WriteByte(t_int8_array)
			binary.Write(buffer, binary.BigEndian, uint16(len(v)))
			for i := 0; i < len(v); i++ {
				buffer.WriteByte(byte(v[i]))
			}
		}
	case []bool:
		{
			buffer.WriteByte(t_bool_array)
			binary.Write(buffer, binary.BigEndian, uint16(len(v)))
			for i := 0; i < len(v); i++ {
				if v[i] {
					buffer.WriteByte(0x01)
				} else {
					buffer.WriteByte(0x00)
				}
			}
		}
	case bool:
		buffer.WriteByte(t_bool)
		binary.Write(buffer, binary.BigEndian, bool(v))
	case uint16:
		buffer.WriteByte(t_uint16)
		binary.Write(buffer, binary.BigEndian, uint16(v))
	case []uint16:
		{
			buffer.WriteByte(t_uint16_array)
			binary.Write(buffer, binary.BigEndian, uint16(len(v)))
			for i := 0; i < len(v); i++ {
				binary.Write(buffer, binary.BigEndian, uint16(v[i]))
			}
		}
	case int16:
		buffer.WriteByte(t_int16)
		binary.Write(buffer, binary.BigEndian, int16(v))
	case []int16:
		{
			buffer.WriteByte(t_int16_array)
			binary.Write(buffer, binary.BigEndian, uint16(len(v)))
			for i := 0; i < len(v); i++ {
				binary.Write(buffer, binary.BigEndian, int16(v[i]))
			}
		}
	case int:
		if cc == 32 {
			buffer.WriteByte(t_int)
			binary.Write(buffer, binary.BigEndian, int32(v))
		}
		if cc == 64 {
			buffer.WriteByte(t_int)
			binary.Write(buffer, binary.BigEndian, int64(v))
		}
	case []int:
		{
			if cc == 32 {
				buffer.WriteByte(t_int_array)
				binary.Write(buffer, binary.BigEndian, uint16(len(v)))
				for i := 0; i < len(v); i++ {
					binary.Write(buffer, binary.BigEndian, int32(v[i]))
				}
			}
			if cc == 64 {
				buffer.WriteByte(t_int_array)
				binary.Write(buffer, binary.BigEndian, uint16(len(v)))
				for i := 0; i < len(v); i++ {
					binary.Write(buffer, binary.BigEndian, int64(v[i]))
				}
			}
		}
	case uint:
		if cc == 32 {
			buffer.WriteByte(t_uint)
			binary.Write(buffer, binary.BigEndian, uint32(v))
		}
		if cc == 64 {
			buffer.WriteByte(t_uint)
			binary.Write(buffer, binary.BigEndian, uint64(v))
		}
	case []uint:
		{
			if cc == 32 {
				buffer.WriteByte(t_uint_array)
				binary.Write(buffer, binary.BigEndian, uint16(len(v)))
				for i := 0; i < len(v); i++ {
					binary.Write(buffer, binary.BigEndian, uint32(v[i]))
				}
			}
			if cc == 64 {
				buffer.WriteByte(t_uint_array)
				binary.Write(buffer, binary.BigEndian, uint16(len(v)))
				for i := 0; i < len(v); i++ {
					binary.Write(buffer, binary.BigEndian, uint64(v[i]))
				}
			}
		}
	case int32:
		buffer.WriteByte(t_int32)
		binary.Write(buffer, binary.BigEndian, int32(v))
	case []int32:
		{
			buffer.WriteByte(t_int32_array)
			binary.Write(buffer, binary.BigEndian, uint16(len(v)))
			for i := 0; i < len(v); i++ {
				binary.Write(buffer, binary.BigEndian, int32(v[i]))
			}
		}
	case uint32:
		buffer.WriteByte(t_uint32)
		binary.Write(buffer, binary.BigEndian, uint32(v))
	case []uint32:
		{
			buffer.WriteByte(t_uint32_array)
			binary.Write(buffer, binary.BigEndian, uint16(len(v)))
			for i := 0; i < len(v); i++ {
				binary.Write(buffer, binary.BigEndian, uint32(v[i]))
			}
		}
	case int64:
		buffer.WriteByte(t_int64)
		binary.Write(buffer, binary.BigEndian, int64(v))
	case []int64:
		{
			buffer.WriteByte(t_int64_array)
			binary.Write(buffer, binary.BigEndian, uint16(len(v)))
			for i := 0; i < len(v); i++ {
				binary.Write(buffer, binary.BigEndian, int64(v[i]))
			}
		}
	case uint64:
		buffer.WriteByte(t_uint64)
		binary.Write(buffer, binary.BigEndian, uint64(v))
	case []uint64:
		{
			buffer.WriteByte(t_uint64_array)
			binary.Write(buffer, binary.BigEndian, uint16(len(v)))
			for i := 0; i < len(v); i++ {
				binary.Write(buffer, binary.BigEndian, uint64(v[i]))
			}
		}
	case float32:
		buffer.WriteByte(t_float32)
		binary.Write(buffer, binary.BigEndian, float32(v))
	case []float32:
		{
			buffer.WriteByte(t_float32_array)
			binary.Write(buffer, binary.BigEndian, uint16(len(v)))
			for i := 0; i < len(v); i++ {
				binary.Write(buffer, binary.BigEndian, float32(v[i]))
			}
		}
	case float64:
		buffer.WriteByte(t_float64)
		binary.Write(buffer, binary.BigEndian, float64(v))
	case []float64:
		{
			buffer.WriteByte(t_float64_array)
			binary.Write(buffer, binary.BigEndian, uint16(len(v)))
			for i := 0; i < len(v); i++ {
				binary.Write(buffer, binary.BigEndian, float64(v[i]))
			}
		}
	case complex64:
		{
			buffer.WriteByte(t_complex64)
			binary.Write(buffer, binary.BigEndian, complex64(v))
		}
	case []complex64:
		{
			buffer.WriteByte(t_complex64_array)
			binary.Write(buffer, binary.BigEndian, uint16(len(v)))
			for i := 0; i < len(v); i++ {
				binary.Write(buffer, binary.BigEndian, complex64(v[i]))
			}
		}
	case complex128:
		{
			buffer.WriteByte(t_complex128)
			binary.Write(buffer, binary.BigEndian, complex128(v))
		}
	case []complex128:
		{
			buffer.WriteByte(t_complex128_array)
			binary.Write(buffer, binary.BigEndian, uint16(len(v)))
			for i := 0; i < len(v); i++ {
				binary.Write(buffer, binary.BigEndian, complex128(v[i]))
			}
		}
	case string:
		buffer.WriteByte(t_string)
		binary.Write(buffer, binary.BigEndian, uint16(len(v)))
		buffer.WriteString(v)
	case []string:
		{
			buffer.WriteByte(t_string_array)
			binary.Write(buffer, binary.BigEndian, uint16(len(v)))
			for i := 0; i < len(v); i++ {
				t := v[i]
				binary.Write(buffer, binary.BigEndian, uint16(len(t)))
				buffer.WriteString(t)
			}
		}
	default:
		return errors.New(Err_DataFormtError)
	}
	return nil
}
